﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using CrawlerCore.XmlData;
using CrawlerCore.MinPrice;
using System.Globalization;
using CrawlerCore.Helper;

namespace CrawlerCore
{
    public class Jetstar
    {
        private string getPosData(SearchInputService inputSearchJetstar)
        {
            StringBuilder postdata = new StringBuilder("");
            postdata.Append("__VIEWSTATE=%2FwEPDwUBMGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFJ01lbWJlckxvZ2luU2VhcmNoVmlldyRtZW1iZXJfUmVtZW1iZXJtZSDCMtVG%2F1lYc7dy4fVekQjBMvD5");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListCurrency=VND");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListFareTypes=I");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketDay1=" + inputSearchJetstar.DepartTime.Day);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketDay2=" + inputSearchJetstar.ReturnTime.Day);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketDay3=");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketMonth1=" + inputSearchJetstar.DepartTime.Year + "-" + inputSearchJetstar.DepartTime.Month);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketMonth2=" + inputSearchJetstar.ReturnTime.Year + "-" + inputSearchJetstar.ReturnTime.Month);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListMarketMonth3=");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListPassengerType_ADT=" + inputSearchJetstar.Adults);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListPassengerType_CHD=" + inputSearchJetstar.Children);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24DropDownListPassengerType_INFANT=" + inputSearchJetstar.Inf);
            string type = "";
            if (inputSearchJetstar.IsRoundTrip)
            {
                type = "RoundTrip";
            }
            else
            {
                type = "OneWay";
            }
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24RadioButtonMarketStructure=" + type);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketDestination1=" + inputSearchJetstar.ArrivalCode);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketDestination2=" + inputSearchJetstar.DepartureCode);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketDestination3");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketOrigin1=" + inputSearchJetstar.DepartureCode);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketOrigin2=" + inputSearchJetstar.ArrivalCode);
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24TextBoxMarketOrigin3=");
            postdata.Append("&ControlGroupSearchView%24ButtonSubmit=");
            postdata.Append("&culture=vi-VN");
            postdata.Append("&date_picker=");
            postdata.Append("&go-booking=");
            postdata.Append("&pageToken:sLkmnwXwAsY=");
            postdata.Append("&ControlGroupSearchView%24AvailabilitySearchInputSearchView%24fromCS=yes");
            return postdata.ToString();
        }
        public Root CreateXmlDocument(SearchInputService input)
        {
            CrawlerHelper helper = new CrawlerHelper();
            Root root = new Root();
            root.Departure = input.DepartureCode;
            root.Arrival = input.ArrivalCode;
            root.AirLine = AirLineName.jetstar;
            HtmlDocument htmld = helper.getDocument("http://booknow.jetstar.com/Search.aspx?culture=vi-VN", "POST", getPosData(input), null);
            //chua 2 bang ve chieu di va ve
            HtmlNodeCollection collection = htmld.DocumentNode.SelectNodes("//table[@class='domestic']");
            #region Depart
            try
            {
                root.outBound = new OutInBound();
                List<Item> items = new List<Item>();
                HtmlNode nodeDepart = collection[0];
                //cac dong chu ban ghi chuyen bay
                var collectiontr = nodeDepart.SelectNodes("tbody/tr").Where(i => i.Attributes.Count == 0).ToList();            
                root.outBound.Items = getItems(collectiontr,input);
            }
            catch { }
            #endregion Depart
            #region Return
            try
            {
                root.inBound = new OutInBound();
                HtmlNode nodeReturn = collection[1];
                //cac dong chu ban ghi chuyen bay
                var collectiontr = nodeReturn.SelectNodes("tbody/tr").Where(i => i.Attributes.Count == 0).ToList();
                root.inBound.Items = getItems(collectiontr,input);
            }
            catch { }
            #endregion Return

            return root;
        }
        private List<Item> getItems(List<HtmlNode> collectiontr,SearchInputService input)
        {
            List<Item> items = new List<Item>();
            foreach (HtmlNode nodetr in collectiontr)
            {
                HtmlNodeCollection collectiontd = nodetr.SelectNodes("td");
                HtmlNode node1;
                Item item = new Item();
                node1 = collectiontd.ElementAt(0).SelectSingleNode("strong");
                item.departureTime = DateTimeHelper.getDate(input.DepartTime, node1.InnerText);
                node1 = collectiontd.ElementAt(1).SelectSingleNode("strong");
                item.arriveTime = DateTimeHelper.getDate(input.DepartTime, node1.InnerText);
                node1 = collectiontd.ElementAt(3).SelectSingleNode("div[1]/label");
                List<Price> prices = new List<Price>();
                prices.Add(new Price { name = "", price = node1.InnerText.Replace("VND ", "").Replace(",", "") });
                node1 = collectiontd.ElementAt(2).SelectSingleNode("div/div[1]//span[@class='flight-no']");
                item.flightNo = node1.InnerText;
                items.Add(item);
                item.price = prices;
            }
            return items;
        }
        public RootMinPrice GetPriceInFare(SearchInputService input)
        {
            CrawlerHelper helper = new CrawlerHelper();
            CookieCollection c = helper.getCookieCollection("http://booknow.jetstar.com/lowfarefinder.aspx", "GET", getGetData(input));
            HtmlDocument htmld = helper.getDocument("http://booknow.jetstar.com/lowfarefinder.aspx", "GET", getGetData(input), c);
            HtmlNodeCollection nodeTemp = htmld.DocumentNode.SelectNodes("//div[@id='departing-flight']/div/div[@class='low-fare-selector']/ul/li");
            RootMinPrice root = new RootMinPrice();
            root.departurePrices = new OutInBoundPrices();
            root.departurePrices.prices = GetListPrices(nodeTemp);
            root.arrivePrices = new OutInBoundPrices();
            nodeTemp = htmld.DocumentNode.SelectNodes("//div[@id='returning-flight']/div/div[@class='low-fare-selector']/ul/li");
            root.arrivePrices.prices = GetListPrices(nodeTemp);
            return root;
        }

        private string getGetData(SearchInputService input)
        {
            StringBuilder get = new StringBuilder("?");
            get.Append("culture=vi-VN");
            string type = "";
            if (input.IsRoundTrip)
            {
                type = "RoundTrip";
            }
            else
            {
                type = "OneWay";
            }
            get.Append("&RadioButtonMarketStructure="+type);
            get.Append("&Origin1="+input.DepartureCode);
            get.Append("&Destination1="+input.ArrivalCode);
            get.Append("&Day1="+input.DepartTime.Day);
            get.Append("&MonthYear1="+input.DepartTime.Year+"-"+input.DepartTime.Month);
            get.Append("&Origin2="+input.ArrivalCode);
            get.Append("&Destination2="+input.DepartureCode);
            get.Append("&Day2="+input.ReturnTime.Day);
            get.Append("&MonthYear2=" + input.ReturnTime.Year + "-" + input.ReturnTime.Month);
            get.Append("&ADT="+input.Adults);
            get.Append("&CHD="+input.Children);
            get.Append("&INFANT="+input.Inf);
            get.Append("&AutoSubmit=Y&ControlGroupCalendarSearchView$AvailabilitySearchInputCalendarSearchView$DropDownListCurrency=VND");
            return get.ToString();
        }

        private List<MinPriceDetail> GetListPrices(HtmlNodeCollection nodeTemp)
        {
            if (nodeTemp == null)
            {
                return null;
            }
            List<MinPriceDetail> l = new List<MinPriceDetail>();
            foreach (HtmlNode nodeLi in nodeTemp)
            {
                try
                {
                    MinPriceDetail mpd = new MinPriceDetail();
                    mpd.Date = DateTime.ParseExact(nodeLi.Attributes["data-date"].Value, "d/M/yyyy", CultureInfo.InvariantCulture);
                    mpd.Price = nodeLi.Attributes["data-price"].Value.Replace(",", "");
                    l.Add(mpd);
                }
                catch { }
            }
            return l;
        }
    }
}